#! /usr/bin/python
#                   _ooOoo_                     
#                  o8888888o                    
#                  88" . "88                    
#                  (| -_- |)                    
#                  O\  =  /O                    
#               ____/`---'\____                 
#             .'  \\|     |//  `.               
#            /  \\|||  :  |||//  \              
#           /  _||||| -:- |||||-  \             
#           |   | \\\  -  /// |   |             
#           | \_|  \---/  |   |             
#           \  .-\__  `-`  ___/-. /             
#         ___`. .'  /--.--\  `. . __            
#      ."" '<  `.___\_<|>_/___.'  >'"".      
#     | | :  `- \`.;`\ _ /`;.`/ - ` : | |       
#     \  \ `-.   \_ __\ /__ _/   .-` /  /       
#======`-.____`-.___\_____/___.-`____.-'======  
#                   `=---='                     
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  
#         Buddha bless me for no bug            
#                                               
####################################################################################
#   Filename    :  StarExec.py                                                      
#   Author      :  Shawn Tan                                                        
#   Date        :  2017.3.21                                                        
#   Description :                                                                   
#   History     :  2017.3.21             creat the document            Shawn Tan    
####################################################################################
import os,random,shutil,stat
from collections import OrderedDict
from StarRE      import *
from StarVar     import *
from StarInfo    import *
from StarThread  import *
from StarEda     import *
from StarTdef    import *
from StarNotes   import *
from StarMisc    import *
from StarLsf     import *

__author__ = 'ST-CAT'


def check_done(lo):

  for i in lo:
    if lo[i] == 'Pending':
      return 1

  return 0

def compiler(option, lo, status, compile_queue, openlava_queue, lsf_queue):
  #compile task process controller
  drm = lo[0].attributes['CONTROL']['drm'][0]

  drm_action_list = ['lsf', 'serial_local', 'parallel_local']

  assert drm in drm_action_list, exec007+drm 

  actions = check_done(status) 

  if actions:
    for i in lo:
      compile_dir  = solve_dir(option, 'FIND_GROUP', i, 0)  
      assert compile_dir in status.keys(), exec008+compile_dir

      if status[compile_dir] == 'Pending': 

        if drm == 'lsf':
          # create the openlava compile thread
          if not openlava_queue.has_key('compile'):
            openlava_queue['compile']=1
            lsf_compiler = THREAD_CONTROL('compile', TESTCASE, option)
            lsf_comp_args=[]
            lsf_comp_args.append(option)
            lsf_comp_args.append(status)
            lsf_comp_args.append(lsf_queue)
            @lsf_compiler.register(name='compile', args=lsf_comp_args)
            def do_lsf_compile(option, status, lsf_queue):

              job_lib = {}
              ls = {}
              status1 = {}

              for i in status.keys():
                if status[i] == 'Pending': 
                  job = i+'/compile_shell'
                  bjob_id=openlava_submitter(option, job)
                  job_lib[i] = bjob_id
                  status[i] = 'Running'
                  lsf_queue.append(bjob_id)

              while (openlava_monitor(option, job_lib, status, ls)):
                time.sleep(1)

            lsf_compiler.setDaemon(True)
            compile_queue['compile']=lsf_compiler
            compile_queue['compile'].start()
          else:
            pass

        else:
          comp_process=THREAD_CONTROL(compile_dir, TESTCASE, option) 
          comp_args=[]
          comp_args.append(compile_dir)
          comp_args.append(status)
          @comp_process.register(name=compile_dir, args=comp_args)
          def do_compile(dir, status):

            status[dir] = 'Running' 

            compile_shell = dir+'/compile_shell'
            result=os.system(compile_shell)

            status[dir] = (result >> 8) == 0 and 'Success' or 'Fail'  

          comp_process.setDaemon(True)
          compile_queue[compile_dir]=comp_process
          compile_queue[compile_dir].start()

      else:
        pass
  else:
    pass

def simulator(option, t, lo, lc, ls, lock, status, sim_queue, openlava_queue, lsf_queue, TYPE=SIMULATION):
  #simulation task process controller

  if len(lo) != 0:

    drm = t.attributes['CONTROL']['drm'][0]

    drm_action_list = ['lsf', 'serial_local', 'parallel_local']

    assert drm in drm_action_list, exec007 

    max_runs_in_parallel = int(t.attributes['CONTROL']['max_runs_in_parallel'][0])

    max_runs_in_parallel = max_runs_in_parallel > 150 and 150 or max_runs_in_parallel

    sim_task=[]

    # get the parallel_num
    if drm == 'lsf':
      if not openlava_queue.has_key('simulation'):
        openlava_queue['simulation']=1
        lsf_simulator = THREAD_CONTROL('compile', TESTCASE, option)
        lsf_sim_args=[]
        lsf_sim_args.append(option)
        lsf_sim_args.append(lo)
        lsf_sim_args.append(lc)
        lsf_sim_args.append(ls)
        lsf_sim_args.append(status)
        lsf_sim_args.append(lsf_queue)
        @lsf_simulator.register(name='compile', args=lsf_sim_args)
        def do_lsf_simulation(option, lo, lc, ls, status, lsf_queue):

          job_lib = {}

          while(check_done(ls) != 0):
            for i in lo:
              seed = i.attributes['SIMULATION']['seed'][0]
              regression_dir = solve_dir(option, 'FIND_REGRESSION', i, 0) 
              compile_dir = solve_dir(option, 'FIND_GROUP', i, 0) 
              sim_dir = solve_dir(option, 'FIND_TEST', i, seed)
              session = i.sessionname
              group   = i.groupname
              test    = i.testname 

              os.environ['RUNSIM_GROUP_COMPILE_DIR'] = compile_dir
              os.environ['RUNSIM_SESSION_COMPILE_DIR'] = regression_dir

              if not status.has_key(session):
                status[session] = {}
                if len(i.attributes['SCRIPT']['pre_session_script']) !=0:
                  os.system(i.attributes['SCRIPT']['pre_session_script'][0])

              if not status[session].has_key(group):
                status[session][group] = {}
                if len(i.attributes['SCRIPT']['pre_group_script'])!=0:
                  os.system(i.attributes['SCRIPT']['pre_group_script'][0])

              if ls[sim_dir] == 'Pending' and lc[compile_dir] == 'Success': 
                job = sim_dir+'/simulation_shell'
                bjob_id=openlava_submitter(option, job)
                job_lib[bjob_id] = copy.deepcopy(i)

                if not status[session][group].has_key(test):
                  status[session][group][test] = {}

                status[session][group][test][seed] = 'UNKNOWN' 
                ls[sim_dir] = 'RUN'

                lsf_queue.append(bjob_id)
              else:
                pass

            time.sleep(1)

          while (openlava_monitor(option, job_lib, status, ls, 'SIM')):
            time.sleep(1)

        lsf_simulator.setDaemon(True)
        sim_queue['simulation']=lsf_simulator
        sim_queue['simulation'].start()
      else:
        pass
    else:
      task_num = max_runs_in_parallel-len(sim_queue.keys())

      distributer(option, lo, sim_task, task_num, lc, ls)  

      len_status = str(len(ls))+'/'+str(len(ls.keys())-len(lo))

      print '\033[35;1m \nSIMULATION STATUS : ['+len_status+']\033[0m'

      for t in sim_task:

        seed = t.attributes['SIMULATION']['seed'][0]

        sim_dir = solve_dir(option, 'FIND_TEST', t, seed)

        compile_dir = solve_dir(option, 'FIND_GROUP', t, seed)

        exec_name='queue'+str(sim_task.index(t))
        executers=THREAD_CONTROL(exec_name, TESTCASE, option)
        exec_args=[]
        exec_args.append(option)
        exec_args.append(exec_name)
        exec_args.append(t)
        exec_args.append(ls)
        exec_args.append(status)
        exec_args.append(lock)
        exec_args.append(TYPE)
        @executers.register(exec_name, exec_args)
        def execute_func(option, name, t, ls, status, lock, TYPE):
          session = t.sessionname
          group   = t.groupname
          test    = t.testname
          seed    = t.attributes['SIMULATION']['seed'][0] 


          regression_dir = solve_dir(option, 'FIND_REGRESSION', t, 0)  
          compile_dir = solve_dir(option, 'FIND_GROUP', t, 0)  
          sim_dir = solve_dir(option, 'FIND_TEST', t, seed)  

          simulation_shell = sim_dir+'/simulation_shell'

          # lock the status 3D dict operation 
          lock.acquire()

          os.environ['RUNSIM_GROUP_COMPILE_DIR'] = compile_dir
          os.environ['RUNSIM_SESSION_COMPILE_DIR'] = regression_dir

          if not status.has_key(session):
            status[session] = {}
            if len(t.attributes['SCRIPT']['pre_session_script']) !=0:
              os.system(t.attributes['SCRIPT']['pre_session_script'][0])

          if not status[session].has_key(group):
            status[session][group] = {}
            if len(t.attributes['SCRIPT']['pre_group_script'])!=0:
              os.system(t.attributes['SCRIPT']['pre_group_script'][0])

          if not status[session][group].has_key(test):
            status[session][group][test] ={}

          lock.release()

          os.environ['RUNSIM_GROUP_COMPILE_DIR'] = ''
          os.environ['RUNSIM_SESSION_COMPILE_DIR'] = ''

          ls[sim_dir] = 'RUN'

          print '\033[36;1m SIMULATION START : '+group+' '+test+' '+seed+'\n\033[0m'

          result = os.system(simulation_shell) 

          result >> 8

          if result:  
            status[session][session][group][test][seed] = 'FAIL'
          else:
            line=script_writer(option, t, 0, 'SCAN', seed)

            sim_result = os.system(line)
            sim_result >> 8

            if sim_result:
              status[session][group][test][seed] = 'FAIL'
            else:
              status[session][group][test][seed] = 'PASS'

          ls[sim_dir] = 'DONE'

        executers.setDaemon(True)
        sim_queue[sim_dir]=executers

      #start the testcase executer
      for i in sim_queue:
        if (not sim_queue[i].is_alive()) and (sim_queue[i].Status == 'PENDING'):
          sim_queue[i].start()
              
  else:
    pass

def distributer(option, lo, task_list, num, lc, ls):
  # distribute task 

  index_list = []

  if num == 0:
    pass
  else:
    for i in range(0, len(lo)):
      seed = lo[i].attributes['SIMULATION']['seed'][0]
      compile_dir = solve_dir(option, 'FIND_GROUP', lo[i], 0)
      sim_dir = solve_dir(option, 'FIND_TEST', lo[i], seed)

      if ls[sim_dir] == 'Pending': 

        if lc[compile_dir] == 'Fail':
          assert False, exec009+compile_dir

        if lc[compile_dir] == 'Success':
          task_list.append(copy.deepcopy(lo[i]))
          index_list.append(sim_dir)

        if len(task_list) >= num:
          break

    for i in lo: 
      seed = i.attributes['SIMULATION']['seed'][0]
      sim_dir = solve_dir(option, 'FIND_TEST', i, seed)

      if sim_dir in index_list: 
        lo.remove(i)
        index_list.remove(sim_dir)

def register(option, testcase, simulation, lc, ls, OpPipe): 

  assert OpPipe[0] == 'RUNSIM_ACT', exec001

  for i in testcase: 
    for j in range(0, i.attributes['CONTROL']['run_num'][0]):

      if '_COM_' in OpPipe[1]:
        if i.groupname in lc.keys():
          pass
        else:
          compile_dir = solve_dir(option, 'BUILD_GROUP', i)
          compile_shell = file(compile_dir+'/compile_shell', 'a')
          compile_shell.write(comp_shell_exit_func)
          end_info='ENV source Fail'

          if '_RTL'  in OpPipe[1]: 

            line=script_writer(option, i, j, 'RTL', 0)
            compile_shell.write(comp_shell_judge_head)
            compile_shell.write(line)
            compile_shell.write(comp_shell_judge_else)
            compile_shell.write('  echo "\033[31;1m ENV source Fail\033[0m"\n')
            compile_shell.write('  :|exit_script\n')
            compile_shell.write(comp_shell_judge_end)
            end_info=' RTL compile Fail'

          if '_VIP'  in OpPipe[1]:
            line=script_writer(option, i, j, 'VIP', 0)
            compile_shell.write(comp_shell_judge_head)
            compile_shell.write(line)
            compile_shell.write(comp_shell_judge_else)
            compile_shell.write('  echo "\033[31;1m RTL compile Fail\033[0m"\n')
            compile_shell.write('  :|exit_script\n')
            compile_shell.write(comp_shell_judge_end)
            end_info=' VIP compile Fail'

          if '_TB'   in OpPipe[1]: 

            line=script_writer(option, i, j, 'TB', 0)
            compile_shell.write(comp_shell_judge_head)
            compile_shell.write(line)
            compile_shell.write(comp_shell_judge_else)
            compile_shell.write('  echo "\033[31;1m VIP compile Fail\033[0m"\n')
            compile_shell.write('  :|exit_script\n')
            compile_shell.write(comp_shell_judge_end)
            end_info=' TestBench compile Fail'

          if '_ELAB' in OpPipe[1]:
            line=script_writer(option, i, j, 'ELAB', 0)
            compile_shell.write(comp_shell_judge_head)
            compile_shell.write(line)
            compile_shell.write(comp_shell_judge_else)
            compile_shell.write('  echo "\033[31;1m TestBench compile Fail\033[0m"\n')
            compile_shell.write('  :|exit_script\n')
            compile_shell.write(comp_shell_judge_end)
            end_info=' Elaboration Fail'


          compile_shell.write('if [ $? -eq 0 ]; then\n')
          compile_shell.write('  exit 0\n')
          compile_shell.write('else\n')
          compile_shell.write('  echo "\033[31;1m '+end_info+'\033[0m"\n')
          compile_shell.write('  exit 1\n')
          compile_shell.write('fi\n')
          compile_shell.close()

          #lc[compile_dir]=[]
          #lc[compile_dir].append('Pending')
          lc[compile_dir] = 'Pending'
      else:
        compile_dir = solve_dir(option, 'FIND_GROUP', i)
        lc[compile_dir] = 'Success'

      if '_SIM' in OpPipe[1]:
        
        simulation.append(copy.deepcopy(i))

        # fetch the seed
        assert not (i.attributes['CONTROL']['run_num'][0] != 1 and option.SEED != None), exec002  
        assert not (i.attributes['CONTROL']['run_num'][0] != 1 and len(i.attributes['SIMULATION']['seed']) !=0), exec002  

        seed = (option.SEED == None) and ((len(i.attributes['SIMULATION']['seed']) == 0) and \
               str(random.randint(0, 2**32)) or i.attributes['SIMULATION']['seed'][0]) or \
               option.SEED

        seed =str(seed)

        sim_dir = solve_dir(option, 'BUILD_TEST', i, seed)
        compile_dir = solve_dir(option, 'FIND_GROUP', i, 0)

        simulation[len(simulation)-1].attributes['SIMULATION']['seed'].append(seed)

        # create the profile simulation dir
        if option.PROFILE_TIME or option.PROFILE_MEM:
          profile_dir = solve_dir((option, 'BUILD_PROFILE', i, seed))

        simulation_shell = file(sim_dir+'/simulation_shell', 'a')
        sim_line = script_writer(option, i, j, 'SIM', seed)
        env_line = script_writer(option, i, j, 'ENV', seed)
        simulation_shell.write(sim_line)
        simulation_shell.close()

        env_csh = open(sim_dir+'/env.sh', 'a')
        env_csh.write(env_line)
        env_csh.close()

        #ls[sim_dir] = []
        ls[sim_dir] = 'Pending'

        #ls[sim_dir].append(seed)
        #ls[sim_dir].append(j)
        #lr[sim_dir] = solve_dir(option, 'FIND_GROUP', i, seed)

def watcher(compdict, simdict, compile_queue, simulation_queue, drm, OpPipe):

  compile_done    = False
  simulation_done = False

  simdone = []

  #manage compile thread
  if drm != 'lsf':
    for i in compdict:
      if compdict[i] != 'Pending' and compdict[i] != 'Running':
        if '_COM_' in OpPipe[1]:
          if compile_queue[i].Stop_Thread:   
            compile_queue[i].stop()

    if ('Pending' not in compdict.values()) and ('Running' not in compdict.values()):
      compile_done = True
    else: 
      compile_done = False

    #manage simulation thread

    for i in simulation_queue:
      if (simdict[i] != 'Pending' and simdict[i] != 'RUN') and simulation_queue[i].Stop_Thread: 
        simulation_queue[i].stop()
        simdone.append(i)


    for i in simdone:
      simulation_queue.pop(i)

    if ('Pending' not in simdict.values()) and ('RUN' not in simdict.values()):
      simulation_done = True
    else: 
      simulation_done = False

  else:
    #manage lsf compile
    if '_COM_' in OpPipe[1]:
      if ('Pending' not in compdict.values()) and ('Running' not in compdict.values()): 
        if compile_queue['compile'].Stop_Thread:
          compile_done = True
        else:
          compile_done = False
      else: 
        compile_done = False

      if compile_done: 
        for i in compdict.keys():
          print info012+' : '+i
    else:
      compile_done = True

    #manage lsf simdone
    simulation_done = True
    for i in simdict:
      if simdict[i] == 'DONE':
        simulation_done = simulation_done and True
      else:
        simulation_done = simulation_done and False

    if simulation_done:
      for i in simulation_queue.keys():
        simulation_queue[i].stop()

    if simulation_done:
      for i in simdict.keys():
        print info012+' : '+i

  return simulation_done and compile_done

def post_scripter(option, lo):
  post_script = []

  # execute post group script
  for i in lo: 
    if i.groupname not in post_script:

      group_dir =  solve_dir(option, 'FIND_GROUP', i, 0)

      os.environ['RUNSIM_GROUP_COMPILE_DIR'] = group_dir

      if len(i.attributes['SCRIPT']['post_group_script']) !=0:
        os.system(i.attributes['SCRIPT']['post_group_script'][0])
      else:
        pass

      post_script.append(i.groupname)

  # execute post session script
  for i in lo: 
    if i.sessionname not in post_script:

      group_dir =  solve_dir(option, 'FIND_REGRESSION', i, 0)

      os.environ['RUNSIM_SESSION_COMPILE_DIR'] = group_dir

      if len(i.attributes['SCRIPT']['post_session_script']) !=0:
        os.system(i.attributes['SCRIPT']['post_session_script'][0])
      else:
        pass

      post_script.append(i.sessionname)

def reporter(option, t, status):

  # report result
  passed=0
  failed=0
  # testname char length
  t_name_len = 0
  # seed char length
  s_name_len = 0

  for i in status:  
    for j in status[i]:  
      for k in status[i][j]:
        if len(k) > t_name_len: 
          t_name_len = len(k)
        for l in status[i][j][k]:
          if len(str(l)) > s_name_len:
            s_name_len = len(l)
          if status[i][j][k][l] == 'PASS': 
            passed+=1
          elif status[i][j][k][l] == 'FAIL':
            failed+=1

  t_name_len += 5
  s_name_len += 3

  num = passed+failed
  dir = solve_dir(option, 'FIND_REGRESSION', t, '0')
  log_dir = dir+'/log'
  print log_dir
  name = status.keys()[0]

  line = '*****************************************************************************\n'
  line = line+'**                       Starblaze Regression Report                       **\n'
  line = line+'*****************************************************************************\n'
  line = line+'Regression Dir : '+solve_dir(option, 'FIND_REGRESSION', t, '0')+'\n'
  line = line+'SESSION : '+name+'\n'
  line = line+'Total TESTCASE NUMBER : '+str(num)+'\n'
  line = line+'\033[32;1m PASSED  TESTCASE NUMBER : '+str(passed)+"\033[0m\n"
  line = line+'\033[31;1m FAILED  TESTCASE NUMBER : '+str(failed)+"\033[0m\n"
  line = line+'*****************************************************************************\n'

  for i in status:  
    line = line+'SESSION : '+i+'\n'
    for j in status[i]:  
      line = line+'  GROUP : '+j+'\n'
      for k in status[i][j]:
        for l in status[i][j][k]:
          if status[i][j][k][l] == 'PASS': 
            line=line+'    TEST : '+k.ljust(t_name_len, ' ')+str(l).ljust(s_name_len, ' ')+'\033[32;1m PASS \033[0m\n'
          elif status[i][j][k][l] == 'FAIL':
            line=line+'    TEST : '+k.ljust(t_name_len, ' ')+str(l).ljust(s_name_len, ' ')+'\033[31;1m FAIL \033[0m\n'

  line = line+'*****************************************************************************'

  print line

  timestamp = time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time()))
  if not os.path.exists(log_dir):
    os.makedirs(log_dir)
  report_file=file(log_dir+'/'+name+'_regression_'+timestamp+'.log','w')
  report_file.write(line)
  report_file.close()

def cleaner(option, regression, OpPipe, lsf_queue):

  'clean the compile/verdi dir'

  testcase=searcher(option, regression)

  for i in testcase:
    compile_dir = solve_dir(option, 'FIND_GROUP', i, '0')
    verdi_dir = solve_dir(option, 'FIND_VERDI', i, '0')

    if os.path.exists(compile_dir):
      shutil.rmtree(compile_dir)

    if os.path.exists(verdi_dir):
      shutil.rmtree(verdi_dir)
 
def scheduler(option, regression, OpPipe, lsf_queue): 

  testcase=searcher(option, regression)
  #define the compile task status info   
  compdict=OrderedDict()
  #define the simulation task status info   
  simdict=OrderedDict()
  simstatus=OrderedDict()

  #thread_queue for parallel_local mode
  compile_queue={}
  simulation = []
  simulation_queue={}

  openlava_queue={}

  if option.Debug: 
    debugger(testcase)
  elif option.C_TEST:
    register(option, testcase, simulation, compdict, simdict, OpPipe) 

    for i in simulation:

      if not simstatus.has_key(session):
        simstatus[session] = {}

      if not simstatus[session].has_key(group):
        simstatus[session][group] = {}

      if not simulation[session][group].has_key(test):
          simstatus[session][group][test] = {}

      if len(i.attributes['SCRIPT']['pre_run_script']):
        c_test = i.attributes['SCRIPT']['pre_run_script'][0]
        session = i.sessionname
        group   = i.groupname
        test    = i.testname
        seed    = i.attributes['SIMULATION']['seed'][0]

        result=os.system(c_test)
        result >> 8
        simstatus[session][group][test][seed] = result == 0 and 'PASS' or 'FAIL'
      else: 
        assert False, exec016+group+'  :  '+test

      report(option, simulation[0], simstatus)

  else: 

    #clean the gabarge before actions
    if option.CLEAN_WITH_OTHER and '_COM_' in  OpPipe[1]:
      cleaner(option, regression, OpPipe, lsf_queue)


    reg_dir = solve_dir(option, 'BUILD_REGRESSION', testcase[0])

    register(option, testcase, simulation, compdict, simdict, OpPipe) 

    case_number=len(simulation)

    status_lock = threading.Lock()

    nt_logo()

    time.sleep(1)

    drm = testcase[0].attributes['CONTROL']['drm'][0]

    while(True):

      compiler(option, testcase, compdict, compile_queue, openlava_queue, lsf_queue)

      simulator(option, testcase[0], simulation, compdict, simdict, status_lock, simstatus, simulation_queue, openlava_queue, lsf_queue)

      if watcher(compdict, simdict, compile_queue, simulation_queue, drm, OpPipe):
        break

      time.sleep(5)

    post_scripter(option, testcase)

    if len(simstatus.keys()) !=0:
      reporter(option, testcase[0], simstatus)

def find_scan_dir(option, lo, status, dir, TYPE, TYPE1=TESTCASE):

  group_dict = {}

  if TYPE=='TEST':
    if len(lo) == 1:
      seed = option.SEED
      session = lo[0].sessionname
      group = lo[0].groupname
      test = lo[0].testname
      group_dir = solve_dir(option, 'FIND_GROUP_ROOT', lo[0], 0) 

      if seed != None:
        sim_dir = solve_dir(option, 'FIND_TEST', lo[0], seed) 
        lo[0].attributes['SIMULATION']['seed'].append(seed)
        group_dict[group_dir]={}
        group_dict[group_dir][sim_dir] = copy.deepcopy(lo[0])
        status[session]={}
        status[session][group]={} 
        status[session][group][test]={} 
        status[session][group][test][seed]=None 
      else: 
        test_dir = solve_dir(option, 'FIND_TEST_ROOT', lo[0], 0) 
        group_dict[group_dir]={}

        for root, dirs, files in os.walk(test_dir): 
          for i in dirs:
            sim_dir = solve_dir(option, 'FIND_TEST', lo[0], i) 
            lo_c = copy.deepcopy(lo[0])
            lo_c.attributes['SIMULATION']['seed'].append(i)
            group_dict[group_dir][sim_dir] = copy.deepcopy(lo_c)
            status[session]={} 
            status[session][group]={} 
            status[session][group][test]={} 
            status[session][group][test][i]=None 

          break
    else:
      for i in lo:

        test_dir = solve_dir(option, 'FIND_TEST_ROOT', i, 0) 

        session  = i.sessionname
        group    = i.groupname
        test     = i.testname

        if not group_dict.has_keys(group):
          group_dict[group_dir]={}

        for root, dirs, files in os.walk(test_dir): 
          for j in dirs:
            lo_c = copy.deepcopy(lo[0])
            lo_c.attributes['SIMULATION']['seed'] = j
            group_dict[group_dir][sim_dir] = copy.deepcopy(lo_c)
            if not status.has_keys(session):
              status[session]={} 
            if not status[session].has_keys(group):
              status[session][group]={} 
            if not status[session][group].has_keys(test):
              status[session][group][test]={} 
            status[session][group][test][j]=[] 

          break
  elif TYPE == 'DIR':

    group_list = []
    test_dict = {}

    for root, dirs, files in os.walk(dir):
      group_list = dirs[:]

      break

    group_list.remove('log')
    raw_dir = dir
    dir = os.getcwd()+'/'+dir
    group_list = [dir+'/'+i+'/sim' for i in group_list]

    for i in group_list: 
      test_dict[i] = []
      for root, dirs, files in os.walk(i):
        for j in dirs:
          test_dict[i].append(j)
        break

    for i in test_dict.keys():
      for j in test_dict[i]:
        test_dir = i+'/'+j
        for root, dirs, files in os.walk(test_dir):

          for k in dirs: 
            o = TYPE1()
            o.attributes={}
            o.attributes['DIR'] = {}
            o.attributes['DIR']['top_dir']=[]
            o.attributes['DIR']['top_dir'].append(raw_dir)

            sim_dir = test_dir+'/'+k
            o.attributes['DIR']['sim_dir']=[]
            o.attributes['DIR']['sim_dir'].append(j)
            o.attributes['DIR']['comp_dir']=[]

            with open(sim_dir+'/env.sh') as info:
              for line in info:
                if 'VAR_SESSION=' in line:
                  session =line.split('"')[1]
                  o.sessionname = session

                  if not status.has_key(session):
                    status[session]={} 

                if 'VAR_GROUP' in line:
                  group =line.split('"')[1]
                  o.groupname = group

                  if not status[session].has_key(group):
                    status[session][group]={} 

                if 'VAR_TEST' in line:
                  test =line.split('"')[1]
                  o.testname = test

                  if not status[session][group].has_key(test):
                    status[session][group][test]={} 

                if 'VAR_SEED' in line:
                  seed =line.split('"')[1]
                  if seed != k: 
                    seed = k
                  o.attributes['SIMULATION']={}
                  o.attributes['SIMULATION']['seed']=[]
                  o.attributes['SIMULATION']['seed'].append(seed)
                  status[session][group][test][seed]=None 

                if 'VAR_PASS_CFG' in line: 
                  if not o.attributes.has_key('SCRIPT'):
                    o.attributes['SCRIPT'] = {}
                  pass_cfg=line.split('"')[1]
                  o.attributes['SCRIPT']['pass_cfg']=[]
                  o.attributes['SCRIPT']['pass_cfg'].append(pass_cfg)

                if 'VAR_FAIL_CFG' in line:
                  if not o.attributes.has_key('SCRIPT'):
                    o.attributes['SCRIPT'] = {}
                  fail_cfg=line.split('"')[1]
                  o.attributes['SCRIPT']['fail_cfg']=[]
                  o.attributes['SCRIPT']['fail_cfg'].append(fail_cfg)

                if 'VAR_IGNORE_CFG' in line:
                  ignore_cfg=line.split('"')[1]
                  if not o.attributes.has_key('SCRIPT'):
                    o.attributes['SCRIPT'] = {}
                  o.attributes['SCRIPT']['ignore_cfg']=[]
                  o.attributes['SCRIPT']['ignore_cfg'].append(ignore_cfg)

            if not group_dict.has_key(i):
              group_dict[i]={}
            group_dict[i][sim_dir] = copy.deepcopy(o)

          break

  return group_dict 

def rescaner(option, regression, OpPipe, lsf_queue):

  status={}


  if option.Test != None: 
    testcase=searcher(option, regression)
    check_mode = 'TEST'
    dir = solve_dir(option, 'FIND_REGRESSION', testcase[0], 0)
  else:
    check_mode = 'DIR'
    testcase=[]
    if option.ReDir:
      dir = option.ReDir
    else:
      dir = os.getcwd+'/build'

  assert os.path.exists(dir), exec015

  group_dict = find_scan_dir(option, testcase, status, dir, check_mode)

  scan_queue=[]

  for i in group_dict:
    scan_thread=THREAD_CONTROL(i, TESTCASE, option)
    scan_args=[]
    scan_args.append(option)
    scan_args.append(group_dict[i])
    scan_args.append(status)
    @scan_thread.register(name=i, args=scan_args)
    def scan_process(option, group_dict, status):
      for i in group_dict:
        seed = group_dict[i].attributes['SIMULATION']['seed'][0]
        session = group_dict[i].sessionname
        group   = group_dict[i].groupname
        test    = group_dict[i].testname

        line = script_writer(option, group_dict[i], 0, 'SCAN',  seed)

        result = os.system(line)

        result >> 8

        if result:
          status[session][group][test][seed] = 'FAIL'
        else:
          status[session][group][test][seed] = 'PASS'
    
    scan_thread.setDaemon(True)
    scan_queue.append(scan_thread)

  for i in scan_queue: 
    i.start()

  while(True):

    finish_scan = True

    for i in scan_queue:
      finish_scan = finish_scan and i.Stop_Thread

    if finish_scan:
      for i in scan_queue:
        i.stop()

      break

    time.sleep(1)

  t =  group_dict[group_dict.keys()[0]][group_dict[group_dict.keys()[0]].keys()[0]]

  reporter(option, t, status)

def verdier(option, regression, OpPipe, lsf_queue):

  testcase=searcher(option, regression)
  assert len(testcase) == 1, exec013

  verdi_cmd = script_writer(option, testcase[0], 0, 'VERDI', option.SEED)
  os.system(verdi_cmd)

def logviewer(option, regression, OpPipe, lsf_queue):

  # view the log 
  testcase=searcher(option, regression)

  assert len(testcase) == 1, exec010
  assert option.SEED != None, exec011

  log_dir = solve_dir(option, 'FIND_TEST', testcase[0], option.SEED)
  log = log_dir+'/'+option.SIM_LOG

  assert os.path.isfile(log), exec012+log

  if option.VIM_VIEW:
    os.system('vim '+log)

  if option.GVIM_VIEW:
    os.system('gvim '+log)

  if option.EMACS_VIEW:
    os.system('emacs '+log)

def reruner(option, regression, OpPipe, lsf_queue):
  pass

